import os
import random
from typing import List, Tuple, Optional

import chardet
import pandas as pd
from moviepy.audio.io.AudioFileClip import AudioFileClip
from moviepy.video.io.VideoFileClip import VideoFileClip

import pyJianYingDraft as draft
import librosa
import soundfile as sf

from combinations.config import OUTPUT_PATH, DRAFT_PATH
from combinations.conf import logger
from pyJianYingDraft import Font_type, trange, Text_style, Clip_settings, Export_framerate, Export_resolution, \
    Text_background
from tqdm import tqdm

# 配置路径常量
AUDIO_SOURCE_DIR = r"D:\模板6_川普锐评\口播音频"
HOT_WORDS_DIR = r"D:\模板6_川普锐评\hot_words"
SRT_SOURCE_DIR = r"D:\模板6_川普锐评\SRT"
IMAGE_FILE_EXTENSIONS = ('.png', '.jpg', '.jpeg')
ORIGINAL_IMAGE_NAMES = [
    "1-phil robertson_2_1.jpg",
    "1-phil robertson_2_2.jpg",
    "1-phil robertson_2_3.jpg",
    "1-phil robertson_2_4.jpg",
    "1-phil robertson_2_5.jpg",
    "1-phil robertson_3_1.jpg",
    "1-phil robertson_3_4.jpg",
    "1-phil_robertson_3_1.jpg",
]


def export_video(project_name: str, output_dir: str, resolution, framerate):
    """
    导出剪映工程为视频文件

    参数:
        project_name (str): 工程名称
        output_dir (str): 输出目录
        resolution: 分辨率设置（来自 Export_resolution）
        framerate: 帧率设置（来自 Export_framerate）

    返回:
        str: 视频文件路径
    """
    try:
        controller = draft.Jianying_controller()
        os.makedirs(output_dir, exist_ok=True)
        video_path = os.path.join(output_dir, f"{project_name}.mp4")
        controller.export_draft(
            project_name,
            video_path,
            resolution=resolution,
            framerate=framerate,
            zi_mu=False,
            kou_tu=False
        )
        logger.info(f"视频导出完成: {video_path}")
        return video_path
    except Exception as e:
        logger.error(f"视频导出失败: {e}")
        return None


def trim_video_based_on_audio(video_path: str, audio_path: str, output_dir: str):
    """
    根据音频时长裁剪视频

    参数:
        video_path (str): 原始视频路径
        audio_path (str): 对应的音频文件路径
        output_dir (str): 裁剪后输出目录
    """
    try:
        audio_clip = AudioFileClip(audio_path)
        adjusted_duration = audio_clip.duration + 1
        audio_clip.close()

        video_clip = VideoFileClip(video_path)

        if video_clip.duration > adjusted_duration:
            trimmed_video = video_clip.subclipped(0, adjusted_duration)
            new_output_path = os.path.join(
                output_dir, "已剪辑", f"剪裁_{os.path.basename(video_path)}"
            )
            os.makedirs(os.path.dirname(new_output_path), exist_ok=True)
            trimmed_video.write_videofile(new_output_path, codec="libx264")
            logger.info(f"视频剪辑成功，保存路径为：{new_output_path}")

        video_clip.close()
    except Exception as e:
        logger.error(f"视频裁剪失败: {e}")


def replace_text_content(script, title: str):
    """
    替换脚本中的文本轨道内容

    参数:
        script: Draft_folder 实例
        title (str): 新的文本内容
    """
    try:
        text_track = script.get_imported_track(draft.Track_type.text, index=0)
        script.replace_text(text_track, 0, text=title)
        logger.info(f"替换【文本】title: {title}")
    except Exception as e:
        logger.error(f"替换文本失败: {e}")


def replace_image_materials(script, hot_word_folder: str):
    """
    替换热点词图片素材，不足5张则循环使用，最多替换前5张

    参数:
        script: Draft_folder 实例
        hot_word_folder (str): 图片所在文件夹路径
    """
    image_files = [
        f for f in os.listdir(hot_word_folder)
        if f.endswith(IMAGE_FILE_EXTENSIONS)
    ]

    if not image_files:
        logger.warning("未找到热点词图片，跳过替换")
        return

    logger.info(f"发现热点词图片数量: {len(image_files)} 张")

    # 循环填充至至少5张图
    while len(image_files) < len(ORIGINAL_IMAGE_NAMES):
        image_files += image_files[:8 - len(image_files)]

    for idx in range(len(ORIGINAL_IMAGE_NAMES)):
        img_file = image_files[idx]
        img_path = os.path.join(hot_word_folder, img_file)
        material_name = ORIGINAL_IMAGE_NAMES[idx]

        try:
            script.replace_material_by_name(
                material_name=material_name,
                material=draft.Video_material(img_path)
            )
            logger.info(f"已替换图像素材: {material_name} -> {img_path}")
        except Exception as e:
            logger.error(f"替换图像素材失败: {material_name} -> {img_path}, 错误: {e}")


def find_audio_and_srt_files(tts_folder: str) -> Tuple[Optional[str], Optional[str]]:
    """
    查找对应的音频和字幕文件

    参数:
        tts_folder (str): 存放音频和 SRT 文件的文件夹
        project_title (str): 当前项目标题（用于匹配 SRT 文件名）

    返回:
        Tuple[str, str]: 音频路径, SRT 路径
    """
    audio_files = [
        f for f in os.listdir(tts_folder)
        if f.endswith(('.wav', '.mp3'))
    ]
    srt_files = [
        f for f in os.listdir(tts_folder)
        if f.endswith('.srt')
    ]

    audio_path = os.path.join(tts_folder, audio_files[0]) if audio_files else None
    srt_path = os.path.join(tts_folder, srt_files[0]) if srt_files else None


    return audio_path, srt_path


def replace_audio_and_import_subtitles(script, audio_path: str, srt_path: str):
    """
    替换音频并导入 SRT 字幕

    参数:
        script: Draft_folder 实例
        audio_path (str): 音频文件路径
        srt_path (str): SRT 字幕文件路径
    """
    if not audio_path:
        logger.warning("未提供音频路径，跳过替换")
        return
    print(audio_path, srt_path)

    try:
        audio_track = script.get_imported_track(draft.Track_type.audio, index=0)
        script.replace_material_by_seg(
            track=audio_track,
            segment_index=0,
            material=draft.Audio_material(audio_path),
            handle_extend=[draft.Extend_mode.extend_tail]
        )
        logger.info(f"替换【音频】素材: 口播音频.wav -> {audio_path}")
    except Exception as e:
        logger.error(f"替换音频失败: {e}")

    if not srt_path:
        logger.warning("未找到 SRT 字幕文件，跳过导入")
        return

    try:
        text_segment = draft.Text_segment(
            "文字",
            trange("0s", "10s"),
            font=Font_type.MyFont凌渡哥哥简,
            style=Text_style(size=10, color=(0.5, 0.5, 0.2), underline=False, align=1),
            background=Text_background(color="#FFFFFF", alpha=0.5)
        )
        text_segment.add_effect("7127656352410881316")  # 添加花字效果

        script.import_srt(srt_path, track_name="字幕2", style_reference=text_segment,
                        clip_settings=draft.Clip_settings(transform_y=-0.65), font_size=10)
        logger.info("SRT字幕成功导入")
    except Exception as e:
        logger.error(f"SRT 导入失败: {e}")


def trump_template_6():
    """
    主函数：批量生成川普风格短视频

    功能说明：
        1. 扫描指定任务目录下的所有子文件夹（每个子文件夹代表一个视频项目）
        2. 每个子文件夹中包含热点词图片、TTS音频及对应的SRT字幕文件
        3. 使用剪映模板批量生成视频并导出
    """
    draft_folder = draft.Draft_folder(DRAFT_PATH)
    task_path = r"D:\PycharmProjects\google-trends\tasks\2025年05月27日06时00分_美国_所有分类"

    # 获取所有子文件夹作为项目名
    project_names = [
        name for name in os.listdir(task_path)
        if os.path.isdir(os.path.join(task_path, name))
    ]

    logger.info(f"共发现 {len(project_names)} 个待处理项目")

    # 使用 tqdm 添加进度条
    for project_name in tqdm(project_names, desc="正在处理视频项目", unit="个项目"):
        project_path = os.path.join(task_path, project_name)

        try:
            # 创建剪映工程副本
            script = draft_folder.duplicate_as_template("模板6_川普锐评", project_name, allow_replace=True)
        except Exception as e:
            logger.error(f"创建剪映工程失败: {e}")
            continue

        # 替换文本内容
        project_title = project_name.split("-")[1]
        replace_text_content(script, project_title)

        # 替换图片素材
        replace_image_materials(script, project_path)
        tts_path = os.path.join(project_path, "tts")
        # 查找音频和字幕文件
        audio_path, srt_path = find_audio_and_srt_files(tts_path)
        # print(audio_path,srt_path)

        if not audio_path:
            logger.warning(f"未找到音频文件，跳过音频替换: {project_name}")
        else:
            # 替换音频 & 导入字幕
            replace_audio_and_import_subtitles(script, audio_path, srt_path)

        # 保存草稿
        try:
            script.save()
        except Exception as e:
            logger.error(f"草稿保存失败: {e}")

        # 导出视频
        export_dir = os.path.join(OUTPUT_PATH, "模版6-川普锐评")
        output_video_path = export_video(
            project_name,
            export_dir,
            resolution=Export_resolution.RES_1080P,
            framerate=Export_framerate.FR_24
        )

        if output_video_path:
            # 裁剪视频
            trim_video_based_on_audio(output_video_path, audio_path, export_dir)

    logger.info("所有项目处理完成")


if __name__ == "__main__":
    trump_template_6()
